package com.apache.ius.controller;

import com.apache.api.api.ApiService;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.api.vo.ResultMsg;
import com.apache.database.constant.SpringContextLoader;
import com.apache.database.model.Page;
import com.apache.ius.common.annotion.BeanFactory;
import com.apache.rpc.common.LoadRpcService;
import com.apache.tools.ConfigUtil;
import com.apache.tools.DataMap;
import com.apache.tools.RequestTools;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.PBOSSOTools;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.*;

/**
 * description:
 * @author dyh 创建时间：2019年02月11日
 */
public abstract class BaseAction {

    protected Logger log = Logger.getLogger(getClass());

    @Autowired(required = false)
    @Qualifier("iusService")
    protected ApiService iusService;

    /**
     * description:  跳到登录页面
     */
    protected void gotoLogin(HttpServletRequest request, HttpServletResponse response, String msg)
            throws IOException {
        ResultMsg rmsg = new ResultMsg("F", StrUtil.doNull(msg, "您还没有登录，请您先登录再进行相应操作"));
        JSONObject array = JSONObject.fromObject(rmsg);
        this.outputJson(array.toString(), response, request.getParameter("callback"));
    }

    protected LoginUser getLoginUser(HttpServletRequest request, HttpServletResponse response) {
        LoginUser loginUser = BeanFactory.getInstance().getLoginUser(request);
        return loginUser;
    }

    /**
     * description:  跳到到错误页面
     */
    protected void gotoErrorPage(HttpServletRequest request, HttpServletResponse response,
            String errors) throws IOException, ServletException {
        ResultMsg rmsg = new ResultMsg("F", StrUtil.doNull(errors, "请求的Action地址未定义"));
        JSONObject array = JSONObject.fromObject(rmsg);
        log.info(array.toString());
        this.outputJson(array.toString(), response, request.getParameter("callback"));
    }

    /**
     * 输出json数据
     *
     * @param json
     * @param response
     */
    protected void outputJson(String json, HttpServletResponse response, String callback)
            throws IOException {
        if (StrUtil.isNotNull(json)) {
            PrintWriter out = response.getWriter();
            if (StrUtil.isNull(callback)) {
                response.setContentType("text/html;charset=UTF-8");
                /**
                 * 解决外部系统跨域访问，Access-Control-Allow-Origin的提示
                 * xhe 20171107
                 * 思路来自：http://blog.csdn.net/fdipzone/article/details/46390573/
                 */
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST,GET");
                response.setHeader("Access-Control-Allow-Credentials", "true");
                out.print(json);
            } else {
                response.setContentType("application/javascript");
                out.print(callback + "(" + json + ")");
            }
            out.flush();
            out.close();
        }
    }

    /**
     * 反射调用类方法32
     *
     * @return 返回方法执行结果
     */
    @SuppressWarnings({ "rawtypes" })
    protected Method doInvoke(Class queryclass, HttpServletRequest request,
            HttpServletResponse response, String methodType, String doCode)
            throws NullPointerException, SecurityException {
        Method[] methods = queryclass.getMethods();//getDeclaredMethods();// 获得类的方法集合
        Method method = null;
        String methodName = methodType + doCode;//方法名
        if (methods != null) {
            int count = methods.length;
            for (int i = 0; i < count; i++) {
                if (methods[i].isAnnotationPresent(RequestMapping.class)) {
                    RequestMapping rm = (RequestMapping) methods[i]
                            .getAnnotation(RequestMapping.class);
                    String val = rm.value()[0];
                    if (val.equals(methodName)) {
                        method = methods[i];
                        break;
                    }
                }
            }
        }
        return method;
    }

    //转换list返回结果
    protected void getListData(ResultEntity entity, Map<String, Object> data) {
        data.put("flag", "T");
        if(null == entity.getEntity()){
            data.put("flag", "F");
            data.put("msg", entity.getMessage());
        }else{
            if (entity.getEntity() instanceof Page) {
                Page page = (Page) entity.getEntity();
                data.put("total", page.getCount());
                data.put("rows", page.getPageObjects());
            } else if (entity.getEntity() instanceof List) {
                List list = (List) entity.getEntity();
                data.put("total", list.size());
                data.put("rows", list);
                data.put("msg",StrUtil.doNull(entity.getMessage(),entity.getResult()));
            } else {
                if(entity.getEntity() instanceof String && "F".equals(String.valueOf(entity.getEntity()))){
                    List list = new ArrayList(0);
                    data.put("total", "0");
                    data.put("rows", list);
                    data.put("flag", "F");
                    data.put("msg", entity.getMessage());
                }else{
                    List list = new ArrayList(1);
                    list.add(entity.getEntity());
                    data.put("total", "1");
                    data.put("rows", list);
                }
            }
        }
    }

    //转换ResultEntity返回结果
    protected Map<String, Object> getResultEntityData(ResultEntity entity){
        Map<String, Object> result = new HashMap();
        if(entity==null){
            result.put("flag", "F");
            result.put("msg", "操作失败");
        }else{
            if("查询成功".equals(entity.getResult()) || ("true".equals(entity.getResult())&&!"F".equals(String.valueOf(entity.getEntity())))  || "T".equals(entity.getResult())){
                result.put("flag","T");
            }else{
                result.put("flag","F");
            }
            result.put("msg", StrUtil.doNull(StrUtil.isNull(entity.getMessage())?"":entity.getMessage(), entity.getResult()));
            if (entity.getEntity() instanceof Page) {
                result.put("flag", "T");
                Page page = (Page)entity.getEntity();
                result.put("total", page.getCount());
                result.put("rows", page.getPageObjects());
            } else if (entity.getEntity() instanceof List) {
                List list = (List)entity.getEntity();
                result.put("flag", "T");
                result.put("total", list.size());
                result.put("rows", list);
            } else if (entity.getEntity() instanceof DataMap) {
                result.put("flag", "T");
                result.put("result", entity.getEntity());//实体存放
            } else if (entity.getEntity() instanceof HashMap) {
                result.put("flag", "T");
                result.put("ids", entity.getEntity());//应对提交submit老版本
                result.put("result", entity.getEntity());//3.2.1新版采用
            }else if(entity.getEntity() instanceof ResultEntity){
                result.put("flag", "T");
                result.put("result", ((ResultEntity) entity.getEntity()).getEntity());
            }else{
                result.put("result", entity.getEntity());
            }
        }
        log.info("getResultEntityData->"+result.toString());
        return result;

    }

    /**
     * description:  获取请求参数
     */
    protected Map<String, String> getParameterMap(HttpServletRequest request) throws IOException {
        Map<String, String> map = new HashMap<String, String>();
        if(request.getAttribute("requestParams") != null){
           return (Map)request.getAttribute("requestParams");
        }
        if(request.getAttribute("defaultParams") != null){
            map = (Map)request.getAttribute("defaultParams");
        }
        String ifBatch = StrUtil.doNull(request.getParameter("ifBatch"), "F");
        String reqIp = RequestTools.getIp(request);
        map.put("Client-IP", reqIp);
        Set keSet = request.getParameterMap().entrySet();
//        log.info("request getParameterMap before--> " + request.getParameterMap());

        Map<String,String> batchObjMap = new HashMap<String,String>();
        if("T".equals(ifBatch)){
            batchObjMap = getChildBatachObjName(keSet);//获取子表对象的objName对象名
        }

        for (Iterator itr = keSet.iterator(); itr.hasNext(); ) {
            Map.Entry me = (Map.Entry) itr.next();
            String ok = String.valueOf(me.getKey());
            if ("ifBatch".equalsIgnoreCase(ok))
                continue;
            Object ov = me.getValue();
            String value = "";
            if (ov instanceof String[]) {
                String[] vls = (String[]) ov;
                if ("F".equalsIgnoreCase(ifBatch)) {//单表插入
                    value = vls[0];
                } else {
                    for (int i = 0; i < vls.length; i++) {////批量处理
                        if (i == vls.length - 1) {
                            value += StrUtil.doNull(vls[i], "_");
                            if(ok.indexOf('.')>-1){
                                String fieldObjname = ok.split("\\.")[0];
                                if(!batchObjMap.containsKey(fieldObjname)){//字段名前缀 是非子表对象
                                    value = vls[i];//字段值为空时不补充下划线_，用于占位符
                                }
                            }
                        } else {
                            value += StrUtil.doNull(vls[i], "_") + "-#-";
                        }
                    }
                }
            } else {
                value = String.valueOf(ov);
            }
            log.info(ok+"->" + value);
            if (StrUtil.isNotNull(value)) {
                String str = new String(value.getBytes("iso8859-1"), "iso8859-1");
                if (value.equals(str)) {
                    value = str;
                }
                map.put(ok, value);
            } else {
                if (ok.indexOf("s_") != -1) {
                    map.put(ok, "is null");//清空
                }
            }
        }
        map.put("sysPass", ConfigUtil.getInstance().interfacePass());
        log.info("request getParameterMap after--> " + map);
        return map;
    }

    private Map<String, String> getChildBatachObjName(Set keSet) {
        Iterator itr11 = keSet.iterator();
        Map<String, String> batchObjMap = new HashMap<String,String>();
        while (itr11.hasNext()) {
            Map.Entry me = (Map.Entry) itr11.next();
            String keys = String.valueOf(me.getKey());
            if(keys.endsWith(".splitAttr")){
                String objName = keys.split(".splitAttr")[0];
                batchObjMap.put(objName, keys);
            }
        }
        log.info("splitAttr.objName->"+batchObjMap);
        return batchObjMap;
    }

    public void setIusService(ApiService iusService) {
        this.iusService = iusService;
    }

    protected ResultEntity doIusService(ParamsVo vo){
        if(null == this.iusService) {
            Object obj = SpringContextLoader.getBean("iusService");
            if (obj != null) {
                this.iusService = (ApiService) obj;
            }
        }
        if(null == this.iusService){
            return LoadRpcService.service().doService("iusService",vo.getMethodKey(),"xml",vo.getParams(),null);
        }else{
            return this.iusService.doService(vo);
        }
    }

    //设置freemark模板所需默认变量参数值
    protected Map getDefaultDataMap(HttpServletRequest request){
        Map<String, Object> parmMap = new HashMap<String,Object>();
        LoginUser loginUser = PBOSSOTools.getLoginUser(request);
//        String root_jsp_path = ConfigUtil.getInstance().getLocalByKey("config.properties", "jsp_path");
//        String service_gateway_url = ConfigUtil.getInstance().getLocalByKey("config.properties", "service_gateway_url");
        Map<String, String> mapConfig = new HashMap<String,String>();
        Map cfMap = ConfigUtil.getInstance().getLocalByKey("config.properties");
        if(cfMap!=null){
            mapConfig.putAll(cfMap);
        }
//        parmMap.putAll(mapConfig);
        parmMap.put("config",mapConfig);
        parmMap.put("loginUser",loginUser);
//        parmMap.put("root_jsp_path",root_jsp_path);

//        parmMap.put("service_gateway_url",service_gateway_url);
        parmMap.put("ctx",request.getContextPath());
        parmMap.put("formToken",UUID.randomUUID().toString());

        return parmMap;
    }

}
